/**
 * 泛型与类结合在一起 可以非常好的配合使用
 */

{
  class NumberCollection {
    data: number[] = [];
    push([...arg]: number[]) {
      this.data.push(...arg);
    }
    shift(): number {
      return this.data.shift();
    }
  }

  let numberCollect = new NumberCollection();
  numberCollect.push([1, 2, 3]); // 只能添加数字类型 添加其他类型会出错

  class StringCollection {
    data: string[] = [];
    push([...args]: string[]) {
      this.data.push(...args);
    }
    shift(): string {
      return this.data.shift();
    }
  }

  let stringCollect = new StringCollection();
  stringCollect.push(["1", "2", "3", "4"]); // 只能添加数字 其他的类型会出错

  /**
   * 相同的功能 却定义了两个类 所以这种情况就时泛型最佳使用场景
   */

  class BaseCollection<T> {
    data: T[] = [];
    push([...args]: T[]) {
      this.data.push(...args);
    }
    shift(): T {
      return this.data.shift();
    }
  }
  /**
   * 完美解决刚刚的问题
   */
  let b1 = new BaseCollection<String>();
  b1.push(["1", "2", "3"]); // b1 new 的是 String类型的泛型集合
  let b2 = new BaseCollection<Number>();
  b2.push([1, 2, 3, 4]); // b2 new 的是 Number 类型的泛型集合

  /**
   * 这个就是泛型的使用场景
   *  除了规范原始类型 还是规范自定义的 type 自定义类型
   */
  type UserType = {
    name: string;
    age: number;
  };
  let b3 = new BaseCollection<UserType>();
  b3.push([
    { name: "Jimmy", age: 22 },
    { name: "xuexue", age: 23 },
  ]);
  console.log(b3.shift());
}
